<template>
  <el-dialog :title="title" :visible="showDialog" @close="close">
    <el-form ref="form" :model="form" :rules="rules">
      <el-form-item label="部门名称" :label-width="formLabelWidth" prop="name">
        <el-input v-model="form.name" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="部门编码" :label-width="formLabelWidth" prop="code">
        <el-input v-model="form.code" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item
        label="部门负责人"
        :label-width="formLabelWidth"
        prop="manager"
      >
        <!-- 下拉框 -->
        <el-select
          @focus="getEmp"
          @blur="$refs.form.validateField('manager')"
          v-model="form.manager"
          placeholder="请选择负责人"
        >
          <el-option
            v-for="item in empList"
            :key="item.id"
            :label="item.username"
            :value="item.username"
          ></el-option>
        </el-select>
      </el-form-item>

      <el-form-item
        label="部门介绍"
        :label-width="formLabelWidth"
        prop="introduce"
      >
        <el-input
          type="textarea"
          :rows="2"
          placeholder="请输入部门介绍"
          v-model="form.introduce"
        >
        </el-input>
      </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="close">取 消</el-button>
      <el-button type="primary" @click="save">确 定</el-button>
    </div>
  </el-dialog>
</template>

<script>
// 导入接口
import { deptListAPI, addDeptAPI, editDeptAPI } from '@/api/department'
import { empSimpleList } from '@/api/employees'
export default {
  name: 'DeptDialog',
  props: {
    // 让父传进来显示和隐藏
    showDialog: {
      type: Boolean,
      default: false
    },
    // 接收传递过来的父级id好用来做新增
    pid: {
      required: true,
      default: ''
    }
  },
  data () {
    // rule就是规则对象（一般没用，无视即可）
    // value就是输入的内容
    // callback是一个回调函数，调用这个回调函数并且里面传入new Error，代表不通过
    // 调用这个函数毛都不传代表通过
    const checkName = async (rule, value, callback) => {
      // 如果我form里的名字和oldForm里的名字一样，证明没有动
      // 没有动可以直接校验通过
      if (this.form.name === this.oldForm.name) {
        return callback()
      }

      // 查出所有部门
      const res = await deptListAPI()
      /*
      // 筛选出同级  this.pid 是传递过来父级id，如果pid等于父级说明是同级
      const list = res.data.depts.filter(v => v.pid === this.pid)
      // 判断是否重复
      if (list.find(v => v.name === value)) {
        callback(new Error('部门名不能重复'))
      }else {
        // 校验通过
        callback()
      }
      */

      // 其实要找部门名是否重复就两个并列条件，1.是同级 2.名字和输入的内容一致
      // 所以其实就是一个逻辑与&&,如果两个都满足一定重复了
      if (
        res.data.depts.find(v => v.pid === this.pid && v.name === value.trim())
      ) {
        callback(new Error('部门名不能重复'))
      } else {
        callback()
      }
    }

    // 校验编码
    const checkCode = async (rule, value, callback) => {
      // 只要编码跟原本的编码还是一样可直接通过
      if (this.form.code === this.oldForm.code) {
        return callback()
      }
      // 查出所有部门列表
      const res = await deptListAPI()
      // 找数组里是否有编码跟我输入的内容一样
      if (res.data.depts.find(v => v.code === value)) {
        callback(new Error('部门编码不能重复'))
      } else {
        callback()
      }
    }

    return {
      form: {},
      // 用来保存原本的值
      oldForm: {},
      formLabelWidth: '120px',
      // 校验规则的地方
      rules: {
        name: [
          { required: true, message: '请输入部门名', trigger: 'blur' },
          { validator: checkName, trigger: 'blur' }
        ],
        code: [
          { required: true, message: '请输入部门编码', trigger: 'blur' },
          // 自定义校验
          { validator: checkCode, trigger: 'blur' }
        ],
        manager: [
          { required: true, message: '请选择负责人', trigger: 'change' }
        ],
        introduce: [
          { required: true, message: '请输入部门介绍', trigger: 'blur' }
        ]
      },
      // 保存员工列表的数组
      empList: []
    }
  },
  methods: {
    // 关闭的事件
    close () {
      // 关闭前手动把form清空
      // 因为如果没有下面这句话会导致编辑时，恢复默认值，那就是恢复到获取的数据
      this.form = {}
      this.oldForm = {}
      // 隐藏之前先恢复了表单的默认值和校验规则
      this.$refs.form.resetFields()

      // 别人在用我这个组件时，他必然可以写 :showDialog.sync="值",会自动生成 @update:showDialog="值=$event"
      this.$emit('update:showDialog', false)
    },

    // 当下拉框获得焦点触发
    async getEmp () {
      const res = await empSimpleList()
      this.empList = res.data
    },

    // 确定的点击事件
    async save () {
      try {
        // 先对整个表单进行校验
        await this.$refs.form.validate()

        if (this.form.id) {
          // 做修改
          await editDeptAPI(this.form)
          this.$message.success('修改成功')

        } else {
          // 代表验证通过，发请求做新增
          await addDeptAPI({
            ...this.form,
            pid: this.pid
          })
          // 弹出成功提示
          this.$message.success('新增成功')
        }

        // 隐藏对话框
        this.close()
        // 加载新数据
        this.$emit('reload')
      } catch {}
    }
  },
  computed: {
    title () {
      return this.form.id ? '查看部门' : '新增部门'
    }
  }
}
</script>

<style></style>
